import type { AxiosError, AxiosResponseHeaders, InternalAxiosRequestConfig, RawAxiosResponseHeaders } from 'axios'
import axios from 'axios'

import { message } from 'ant-design-vue'

// 这里是用于设定请求后端时，所用的 Token KEY
// 可以根据自己的需要修改，常见的如 Access-Token，Authorization
// 需要注意的是，请尽量保证使用中横线`-` 来作为分隔符，
// 避免被 nginx 等负载均衡器丢弃了自定义的请求头
const REQUEST_TOKEN_KEY = 'Authorization'

// 获取接口 API URL
export function getSideBarApiURL() {
  return window.location.host.toLowerCase() === 'cscompany-gjp.superhrai.com'
    ? 'https://cscompanyapi-gjp.superhrai.com'
    : window.location.host.toLowerCase() === 'company-gjp.superhrai.com'
      ? 'https://companyapi-gjp.superhrai.com'
      : import.meta.env.VITE_APP_API_FORCE_URL || import.meta.env.VITE_APP_API_BASE_URL
}

// 获取上传接口 API URL
export function getUploadApiURL() {
  return window.location.host.toLowerCase() === 'cscompany-gjp.superhrai.com'
    ? 'https://cscompanyapi-gjp.superhrai.com'
    : window.location.host.toLowerCase() === 'company-gjp.superhrai.com'
      ? 'https://companyapi-gjp.superhrai.com'
      : import.meta.env.VITE_APP_API_FORCE_URL || import.meta.env.VITE_APP_API_UPLOAD_URL
}

// 创建 axios 实例
const requestUpload = axios.create({
  // API 请求的默认前缀
  baseURL: getUploadApiURL(),
  timeout: 1000 * 60, // 请求超时时间
  withCredentials: true,
})

// 创建 axios 实例
const requestSiderbar = axios.create({
  // API 请求的默认前缀
  baseURL: getSideBarApiURL(),
  timeout: 1000 * 60, // 请求超时时间
  withCredentials: true,
})

export type RequestError = AxiosError<{
  message?: string
  result?: any
  errorMessage?: string
}>

export interface HttpResponse<T = any> {
  /**
   * 0 表示成功 其他表示失败
   * 0 means success, others means fail
   */
  code: number
  success: boolean
  data: T
  message: string
}

let authWarningToasted = false
export function setAuthWarningToasted(value: boolean) {
  authWarningToasted = value
}
function handleAuthError(status: 401 | 403, error: RequestError): Promise<any> {
  const { data = {} } = error.response!
  if (authWarningToasted === false) {
    if (status === 403) {
      // 403 无权限
      message.error(data.message || '你没有操作权限')
    } else if (status === 401){
      // 401 未登录/未授权
      message.error(data.message || '请先登录')
    }
    setAuthWarningToasted(true)
    removeStorageToken()
    toLogin({ reload: false })
  }
  return Promise.reject(error)
}
// 异常拦截处理器
function errorHandler(error: RequestError): Promise<any> {
  if (error.response) {
    const { data = {}, status } = error.response
    if (status === 403 || status === 401) {
      return handleAuthError(status, error)
    } else {
      const errMsg = data.message || error.message
      if (errMsg) {
        message.error(errMsg)
      }
    }
  } else {
    message.error(error.message)
  }

  console.error('Request error:', error)
  return Promise.reject(error)
}

// 请求拦截器
function requestHandler(
  config: InternalAxiosRequestConfig,
): InternalAxiosRequestConfig | Promise<InternalAxiosRequestConfig> {
  const savedToken = getStorageToken()
  // 如果 token 存在
  // 让每个请求携带自定义 token, 请根据实际情况修改
  if (savedToken)
    config.headers[REQUEST_TOKEN_KEY] = `Bearer ${savedToken}`

  return config
}

// 响应拦截器
function responseHandler(response: { data: HttpResponse, headers: AxiosResponseHeaders | RawAxiosResponseHeaders }) {
  const token = response.headers['access-token'] || response.headers['Access-Token']
  import.meta.env.DEV && console.log('response token', token)
  if (token === 'invalid_token') {
    removeStorageToken()
  }
  else if (token) {
    setStorageToken(token)
    setAuthWarningToasted(false)
  }

  if (response.data.code === 0) {
    return response.data.data
  }

  if (response.data.message) {
    message.error(response.data.message)
  }

  // 如果是 blob 类型直接返回
  if (response.data instanceof Blob) {
    return response.data
  }

  console.error('Request error:', response.data)

  const error = new Error(`Error ${response?.data?.message || '操作失败'} `)
  // @ts-ignore
  error.response = response.data
  throw error
}

requestUpload.interceptors.request.use(requestHandler, errorHandler)
requestUpload.interceptors.response.use(responseHandler, errorHandler)

requestSiderbar.interceptors.request.use(requestHandler, errorHandler)
requestSiderbar.interceptors.response.use(responseHandler, errorHandler)

export { requestUpload, requestSiderbar }
